﻿using EMall.Application;
using EMall.Query;
using EMall.Uow;
using System.Net;
using System;

namespace EMall.OrderService.Orders
{
    public class OrderAppService : ApplicationService, IOrderAppService
    {
        private readonly IOrderRepository _orderRepository;
        public OrderAppService(
            IOrderRepository orderRepository)
        {
            _orderRepository = orderRepository;
        }
        [UnitOfWork]
        public async Task CreateAsync(CreateOrderDto input)
        {
            var buyer = new Buyer(input.BuyerId, input.BuyerName);
            var address = new Address(input.Province, input.City, input.Country, input.Street, input.Detail);
            var order = new Order(buyer, address);
            foreach (var orderItem in input.OrderItems)
            {
                order.AddOrderItem(orderItem.ProductId, orderItem.ProductName, orderItem.UnitPrice, orderItem.Quantity);
            }
            await _orderRepository.AddAsync(order);
        }
        [UnitOfWork]
        public async Task UpdateAsync(UpdateOrderDto input)
        {
            var buyer = new Buyer(input.BuyerId, input.BuyerName);
            var address = new Address(input.Province, input.City, input.Country, input.Street, input.Detail);
            var order = await _orderRepository.GetAsync(input.Id);
            order.Update(buyer, address);
        }
        [UnitOfWork]
        public async Task ShipAsync(ShipOrderDto input)
        {
            var order = await _orderRepository.GetAsync(input.Id);
            order.SetShippedStatus();
        }
        [UnitOfWork]
        public async Task ReceiveAsync(ReceiveOrderDto input)
        {
            var order = await _orderRepository.GetAsync(input.Id);
            order.SetCancelledStatus();
        }
        [UnitOfWork]
        public async Task CancelAsync(CancelOrderDto input)
        {
            var order = await _orderRepository.GetAsync(input.Id);
            order.SetCancelledStatus();
        }
        [UnitOfWork]
        public async Task RefundAsync(RefundOrderDto input)
        {
            var order = await _orderRepository.GetAsync(input.Id);
            order.SetRefundedStatus();
        }
        public async Task<OrderDto> GetAsync(int id)
        {
            var order = await QueryService.GetAsync<Order, int>(id);
            return Mapper.Map<OrderDto>(order);
        }
        public async Task<IPagedList<OrderListDto>> GetPagedListAsync(GetOrderListPagingAndSortingQueryDto input)
        {
            var pagedData = await QueryService.GetQueryable<Order>()
               .Sorting(input.Sorting)
               .ToPagedListAsync(input.PageIndex, input.PageSize);
            return Mapper.Map<Order, OrderListDto>(pagedData);
        }
    }
}